home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
United Public Domain Gold 4
/
United Public Domain Gold 4.iso
/
fredfish
/
ff.0249.dms
/
ff.0249.adf
/
Automata
/
AutomaTron.c
< prev
next >
Wrap
Text File
|
1989-09-14
|
36KB
|
1,190 lines
/*
AutomaTron.c Gary Teachout August 1989
lc -L AutomaTron To compile and link with Lattice 5.0
*/
#include <intuition/intuition.h>
#define FPEN 7
#define DPEN 7
#define BPEN 0
#define CMAX 8
#define SWIDTH 320
#define SHEIGHT 200
#define PLANES 3
#define RULEMAX ( 7 * 7 ) + 1
#define SEEDMAX 80
#define STOPMODE 1
#define RULEMODE 2
#define SEEDMODE 4
struct menubox
{
struct MenuItem item ;
struct IntuiText text ;
} ;
struct IntuitionBase *IntuitionBase ;
struct GfxBase *GfxBase ;
struct Screen *screen ;
struct Window *window ;
struct IntuiMessage *mes ;
ULONG class ;
USHORT code ;
struct NewScreen ns =
{
0 , 0 , SWIDTH , SHEIGHT , PLANES , DPEN , BPEN , 0 ,
CUSTOMSCREEN , NULL , " AutomaTron" , NULL , NULL
} ;
struct TextAttr stext = { "topaz.font" , 8 , 0 , 0 } ;
struct NewWindow
nw = /* for display window */
{
0 , 0 , SWIDTH , SHEIGHT , DPEN , BPEN ,
MENUPICK | MENUVERIFY ,
SMART_REFRESH | ACTIVATE | BACKDROP | BORDERLESS ,
NULL , NULL , NULL ,
NULL , NULL , 0 , 0 , 0 , 0 , CUSTOMSCREEN
} ,
rnw = /* for string request window */
{
0 , 30 , 320 , 38 , DPEN , 3 ,
GADGETUP ,
SMART_REFRESH | ACTIVATE | WINDOWDRAG ,
NULL , NULL , NULL ,
NULL , NULL , 0 , 0 , 0 , 0 , CUSTOMSCREEN
} ;
/* string request gadgets and stuff */
struct Gadget rgadget[ 3 ] =
{
{ NULL , 4 , 13 , 312 , 8 ,
GADGHCOMP , TOGGLESELECT | RELVERIFY | STRINGCENTER , STRGADGET ,
NULL , NULL , NULL , 0 , NULL , 1 , NULL } ,
{ NULL , 8 , 25 , 100 , 10 ,
GADGHCOMP , RELVERIFY , BOOLGADGET ,
NULL , NULL , NULL , 0 , NULL , 2 , NULL } ,
{ NULL , 212 , 25 , 100 , 10 ,
GADGHCOMP , RELVERIFY , BOOLGADGET ,
NULL , NULL , NULL , 0 , NULL , 3 , NULL }
} ;
struct StringInfo reqinfo ;
UBYTE buff[ SEEDMAX + 1 ] ,
ubuff[ SEEDMAX + 1 ] ;
struct Border borders[ 3 ] =
{
{ -2 , -2 , 4 , 0 , JAM1 , 5 } ,
{ -1 , -1 , 2 , 0 , JAM1 , 5 } ,
{ -1 , -1 , 1 , 0 , JAM1 , 5 } ,
} ;
short xyborders[ 2 ][ 10 ] =
{
{ 0 , 0 , 315 , 0 , 315 , 11 , 0 , 11 , 0 , 0 } ,
{ 0 , 0 , 101 , 0 , 101 , 11 , 0 , 11 , 0 , 0 } ,
} ;
struct IntuiText gtext[ 2 ] =
{
{ FPEN , BPEN , JAM1 , 42 , 2 , NULL , "OK" , NULL } ,
{ FPEN , BPEN , JAM1 , 26 , 2 , NULL , "CANCEL" , NULL }
} ;
/* display window menus */
struct Menu menulist[ 3 ] =
{
{ NULL , 1 , 0 , 90 , 8 , MENUENABLED , " Control" , NULL } ,
{ NULL , 91 , 0 , 90 , 10 , MENUENABLED , " Rules" , NULL } ,
{ NULL , 181 , 0 , 90 , 10 , MENUENABLED , " Seeds" , NULL }
} ;
struct menubox
controlmenu[ 6 ] =
{
{
{ NULL , 0 , 0 , 140 , 11 ,
ITEMTEXT | ITEMENABLED | HIGHCOMP | COMMSEQ ,
0 , NULL , NULL , 'S' , NULL , NULL } ,
{ FPEN , BPEN , JAM1 , 10 , 2 , NULL , "Stop" , NULL }
} ,
{
{ NULL , 0 , 11 , 140 , 11 ,
ITEMTEXT | ITEMENABLED | HIGHCOMP | COMMSEQ ,
0 , NULL , NULL , 'C' , NULL , NULL } ,
{ FPEN , BPEN , JAM1 , 10 , 2 , NULL , "Continue" , NULL }
} ,
{
{ NULL , 0 , 22 , 140 , 11 ,
ITEMTEXT | ITEMENABLED | HIGHCOMP ,
0 , NULL , NULL , 0 , NULL , NULL } ,
{ FPEN , BPEN , JAM1 , 10 , 2 , NULL , "Precision" , NULL }
} ,
{
{ NULL , 0 , 33 , 140 , 11 ,
ITEMTEXT | ITEMENABLED | HIGHCOMP ,
0 , NULL , NULL , 0 , NULL , NULL } ,
{ FPEN , BPEN , JAM1 , 10 , 2 , NULL , "Neighborhood" , NULL }
} ,
{
{ NULL , 0 , 44 , 140 , 11 ,
ITEMTEXT | ITEMENABLED | HIGHCOMP ,
0 , NULL , NULL , 0 , NULL , NULL } ,
{ FPEN , BPEN , JAM1 , 10 , 2 , NULL , "Modes" , NULL }
} ,
{
{ NULL , 0 , 66 , 140 , 11 ,
ITEMTEXT | ITEMENABLED | HIGHCOMP | COMMSEQ ,
0 , NULL , NULL , 'Q' , NULL , NULL } ,
{ FPEN , BPEN , JAM1 , 10 , 2 , NULL , "Quit" , NULL }
}
} ,
rulesmenu[ 2 ] =
{
{
{ NULL , 0 , 0 , 110 , 11 ,
ITEMTEXT | ITEMENABLED | HIGHCOMP | COMMSEQ ,
0 , NULL , NULL , 'R' , NULL , NULL } ,
{ FPEN , BPEN , JAM1 , 10 , 2 , NULL , "Random" , NULL }
} ,
{
{ NULL , 0 , 11 , 110 , 11 ,
ITEMTEXT | ITEMENABLED | HIGHCOMP ,
0 , NULL , NULL , 0 , NULL , NULL } ,
{ FPEN , BPEN , JAM1 , 10 , 2 , NULL , "Custom" , NULL }
}
} ,
seedsmenu[ 3 ] =
{
{
{ NULL , 0 , 0 , 120 , 11 ,
ITEMTEXT | ITEMENABLED | HIGHCOMP | COMMSEQ ,
0 , NULL , NULL , 'P' , NULL , NULL } ,
{ FPEN , BPEN , JAM1 , 10 , 2 , NULL , "Random" , NULL }
} ,
{
{ NULL , 0 , 11 , 120 , 11 ,
ITEMTEXT | ITEMENABLED | HIGHCOMP ,
0 , NULL , NULL , 0 , NULL , NULL } ,
{ FPEN , BPEN , JAM1 , 10 , 2 , NULL , "Custom" , NULL }
} ,
{
{ NULL , 0 , 22 , 120 , 11 ,
ITEMTEXT | ITEMENABLED | HIGHCOMP | COMMSEQ ,
0 , NULL , NULL , 'O' , NULL , NULL } ,
{ FPEN , BPEN , JAM1 , 10 , 2 , NULL , "Old Seed" , NULL }
}
} ,
precisionsub[ 3 ] =
{
{
{ NULL , 130 , 0 , 120 , 11 ,
ITEMTEXT | ITEMENABLED | HIGHCOMP | CHECKIT ,
0 , NULL , NULL , 0 , NULL , NULL } ,
{ FPEN , BPEN , JAM1 , 25 , 2 , NULL , "160 Cells" , NULL }
} ,
{
{ NULL , 130 , 11 , 120 , 11 ,
ITEMTEXT | ITEMENABLED | HIGHCOMP | CHECKIT | CHECKED ,
0 , NULL , NULL , 0 , NULL , NULL } ,
{ FPEN , BPEN , JAM1 , 25 , 2 , NULL , "320 Cells" , NULL }
} ,
{
{ NULL , 130 , 22 , 120 , 11 ,
ITEMTEXT | ITEMENABLED | HIGHCOMP | CHECKIT ,
0 , NULL , NULL , 0 , NULL , NULL } ,
{ FPEN , BPEN , JAM1 , 25 , 2 , NULL , "640 Cells" , NULL }
}
} ,
neighborsub[ 6 ] =
{
{
{ NULL , 130 , 0 , 120 , 11 ,
ITEMTEXT | ITEMENABLED | HIGHCOMP | CHECKIT ,
0x3e , NULL , NULL , 0 , NULL , NULL } ,
{ FPEN , BPEN , JAM1 , 25 , 2 , NULL , "2 Cells" , NULL }
} ,
{
{ NULL , 130 , 11 , 120 , 11 ,
ITEMTEXT | ITEMENABLED | HIGHCOMP | CHECKIT | CHECKED ,
0x3d , NULL , NULL , 0 , NULL , NULL } ,
{ FPEN , BPEN , JAM1 , 25 , 2 , NULL , "3 Cells" , NULL }
} ,
{
{ NULL , 130 , 22 , 120 , 11 ,
ITEMTEXT | ITEMENABLED | HIGHCOMP | CHECKIT ,
0x3b , NULL , NULL , 0 , NULL , NULL } ,
{ FPEN , BPEN , JAM1 , 25 , 2 , NULL , "4 Cells" , NULL }
} ,
{
{ NULL , 130 , 33 , 120 , 11 ,
ITEMTEXT | ITEMENABLED | HIGHCOMP | CHECKIT ,
0x37 , NULL , NULL , 0 , NULL , NULL } ,
{ FPEN , BPEN , JAM1 , 25 , 2 , NULL , "5 Cells" , NULL }
} ,
{
{ NULL , 130 , 44 , 120 , 11 ,
ITEMTEXT | ITEMENABLED | HIGHCOMP | CHECKIT ,
0x2f , NULL , NULL , 0 , NULL , NULL } ,
{ FPEN , BPEN , JAM1 , 25 , 2 , NULL , "6 Cells" , NULL }
} ,
{
{ NULL , 130 , 55 , 120 , 11 ,
ITEMTEXT | ITEMENABLED | HIGHCOMP | CHECKIT ,
0x1f , NULL , NULL , 0 , NULL , NULL } ,
{ FPEN , BPEN , JAM1 , 25 , 2 , NULL , "7 Cells" , NULL }
}
} ,
modesub[ 3 ] =
{
{
{ NULL , 130 , 0 , 120 , 11 ,
ITEMTEXT | ITEMENABLED | HIGHCOMP | MENUTOGGLE | CHECKIT ,
0 , NULL , NULL , 0 , NULL , NULL } ,
{ FPEN , BPEN , JAM1 , 25 , 2 , NULL , "Stop" , NULL }
} ,
{
{ NULL , 130 , 11 , 120 , 11 ,
ITEMTEXT | ITEMENABLED | HIGHCOMP
| MENUTOGGLE | CHECKIT | CHECKED ,
0 , NULL , NULL , 0 , NULL , NULL } ,
{ FPEN , BPEN , JAM1 , 25 , 2 , NULL , "New Seed" , NULL }
} ,
{
{ NULL , 130 , 22 , 120 , 11 ,
ITEMTEXT | ITEMENABLED | HIGHCOMP
| MENUTOGGLE | CHECKIT | CHECKED ,
0 , NULL , NULL , 0 , NULL , NULL } ,
{ FPEN , BPEN , JAM1 , 25 , 2 , NULL , "New Rule" , NULL }
}
} ;
/* assorted global variables */
USHORT line , /* display y */
stopflag = 0 ,
neighborhood = 3 ,
precision = SWIDTH ,
modes = SEEDMODE | RULEMODE ;
UBYTE colors = 4 ,
cells1[ 640 ] , /* cell array 1 */
cells2[ 640 ] , /* cell array 2 */
*old , /* pointer to old cells */
*new , /* pointer to new cells */
oldseed[ SEEDMAX + 1 ] = { 1 , 255 } ,
rule[ RULEMAX ] = { 0 , 1 , 3 , 1 , 1 , 2 , 3 , 0 , 0 } ;
UBYTE ctab[ CMAX ][ 3 ] = /* screen colors */
{
{ 0 , 0 , 0 } ,
{ 15 , 0 , 0 } ,
{ 0 , 15 , 0 } ,
{ 0 , 0 , 15 } ,
{ 14 , 14 , 0 } ,
{ 14 , 0 , 14 } ,
{ 0 , 14 , 14 } ,
{ 14 , 14 , 14 }
} ;
char *AllocMem() ;
struct Screen *OpenScreen() ;
struct Window *OpenWindow() ;
struct IntuiMessage *GetMsg() ;
void cleanup( void ) ;
void stepauto( void ) ;
void display( void ) ;
UBYTE random( UBYTE ) ;
void randrule( void ) ;
void randseed( void ) ;
void handlemsg( void ) ;
void handlemenu( void ) ;
void stoploop( void ) ;
short stringreq( UBYTE * , short ) ;
void main()
{
short i ;
IntuitionBase = ( struct IntuitionBase * )
OpenLibrary( "intuition.library" , 33 ) ;
if ( ! IntuitionBase )
cleanup() ;
GfxBase = ( struct GfxBase * )
OpenLibrary( "graphics.library" , 33 ) ;
if ( ! GfxBase )
cleanup() ;
ns.Font = &stext ;
screen = OpenScreen( &ns ) ;
if ( ! screen )
cleanup() ;
for ( i = 0 ; i < CMAX ; i ++ )
SetRGB4( &screen->ViewPort , i , ctab[ i ][ 0 ] ,
ctab[ i ][ 1 ] ,
ctab[ i ][ 2 ] ) ;
rgadget[ 0 ].NextGadget = &rgadget[ 1 ] ;
rgadget[ 1 ].NextGadget = &rgadget[ 2 ] ;
rgadget[ 0 ].SpecialInfo = ( APTR ) &reqinfo ;
reqinfo.Buffer = buff ;
reqinfo.UndoBuffer = ubuff ;
rgadget[ 0 ].GadgetRender = ( APTR ) &borders[ 0 ] ;
rgadget[ 1 ].GadgetRender = ( APTR ) &borders[ 1 ] ;
rgadget[ 2 ].GadgetRender = ( APTR ) &borders[ 2 ] ;
borders[ 0 ].XY = &xyborders[ 0 ][ 0 ] ;
borders[ 1 ].XY = &xyborders[ 1 ][ 0 ] ;
borders[ 2 ].XY = &xyborders[ 1 ][ 0 ] ;
rgadget[ 1 ].GadgetText = >ext[ 0 ] ;
rgadget[ 2 ].GadgetText = >ext[ 1 ] ;
rnw.FirstGadget = &rgadget[ 0 ] ;
nw.Screen = screen ;
window = OpenWindow( &nw ) ;
if ( ! window )
cleanup() ;
SetAPen( window->RPort , 7 ) ;
Move( window->RPort , 10 , 140 ) ;
Text( window->RPort , "One Dimensional Cellular Automation" , 35 ) ;
Move( window->RPort , 10 , 152 ) ;
Text( window->RPort , "by Gary Teachout" , 17 ) ;
menulist[ 0 ].NextMenu = &menulist[ 1 ] ;
menulist[ 0 ].FirstItem = &controlmenu[ 0 ].item ;
menulist[ 1 ].NextMenu = &menulist[ 2 ] ;
menulist[ 1 ].FirstItem = &rulesmenu[ 0 ].item ;
menulist[ 2 ].FirstItem = &seedsmenu[ 0 ].item ;
controlmenu[ 0 ].item.ItemFill = ( APTR ) &controlmenu[ 0 ].text ;
controlmenu[ 0 ].item.NextItem = &controlmenu[ 1 ].item ;
controlmenu[ 1 ].item.ItemFill = ( APTR ) &controlmenu[ 1 ].text ;
controlmenu[ 1 ].item.NextItem = &controlmenu[ 2 ].item ;
controlmenu[ 2 ].item.ItemFill = ( APTR ) &controlmenu[ 2 ].text ;
controlmenu[ 2 ].item.NextItem = &controlmenu[ 3 ].item ;
controlmenu[ 3 ].item.ItemFill = ( APTR ) &controlmenu[ 3 ].text ;
controlmenu[ 3 ].item.NextItem = &controlmenu[ 4 ].item ;
controlmenu[ 4 ].item.ItemFill = ( APTR ) &controlmenu[ 4 ].text ;
controlmenu[ 4 ].item.NextItem = &controlmenu[ 5 ].item ;
controlmenu[ 5 ].item.ItemFill = ( APTR ) &controlmenu[ 5 ].text ;
controlmenu[ 2 ].item.SubItem = &precisionsub[ 0 ].item ;
precisionsub[ 0 ].item.ItemFill = ( APTR ) &precisionsub[ 0 ].text ;
precisionsub[ 0 ].item.NextItem = &precisionsub[ 1 ].item ;
precisionsub[ 1 ].item.ItemFill = ( APTR ) &precisionsub[ 1 ].text ;
precisionsub[ 1 ].item.NextItem = &precisionsub[ 2 ].item ;
precisionsub[ 2 ].item.ItemFill = ( APTR ) &precisionsub[ 2 ].text ;
controlmenu[ 3 ].item.SubItem = &neighborsub[ 0 ].item ;
neighborsub[ 0 ].item.ItemFill = ( APTR ) &neighborsub[ 0 ].text ;
neighborsub[ 0 ].item.NextItem = &neighborsub[ 1 ].item ;
neighborsub[ 1 ].item.ItemFill = ( APTR ) &neighborsub[ 1 ].text ;
neighborsub[ 1 ].item.NextItem = &neighborsub[ 2 ].item ;
neighborsub[ 2 ].item.ItemFill = ( APTR ) &neighborsub[ 2 ].text ;
neighborsub[ 2 ].item.NextItem = &neighborsub[ 3 ].item ;
neighborsub[ 3 ].item.ItemFill = ( APTR ) &neighborsub[ 3 ].text ;
neighborsub[ 3 ].item.NextItem = &neighborsub[ 4 ].item ;
neighborsub[ 4 ].item.ItemFill = ( APTR ) &neighborsub[ 4 ].text ;
neighborsub[ 4 ].item.NextItem = &neighborsub[ 5 ].item ;
neighborsub[ 5 ].item.ItemFill = ( APTR ) &neighborsub[ 5 ].text ;
controlmenu[ 4 ].item.SubItem = &modesub[ 0 ].item ;
modesub[ 0 ].item.ItemFill = ( APTR ) &modesub[ 0 ].text ;
modesub[ 0 ].item.NextItem = &modesub[ 1 ].item ;
modesub[ 1 ].item.ItemFill = ( APTR ) &modesub[ 1 ].text ;
modesub[ 1 ].item.NextItem = &modesub[ 2 ].item ;
modesub[ 2 ].item.ItemFill = ( APTR ) &modesub[ 2 ].text ;
rulesmenu[ 0 ].item.ItemFill = ( APTR ) &rulesmenu[ 0 ].text ;
rulesmenu[ 0 ].item.NextItem = &rulesmenu[ 1 ].item ;
rulesmenu[ 1 ].item.ItemFill = ( APTR ) &rulesmenu[ 1 ].text ;
seedsmenu[ 0 ].item.ItemFill = ( APTR ) &seedsmenu[ 0 ].text ;
seedsmenu[ 0 ].item.NextItem = &seedsmenu[ 1 ].item ;
seedsmenu[ 1 ].item.ItemFill = ( APTR ) &seedsmenu[ 1 ].text ;
seedsmenu[ 1 ].item.NextItem = &seedsmenu[ 2 ].item ;
seedsmenu[ 2 ].item.ItemFill = ( APTR ) &seedsmenu[ 2 ].text ;
SetMenuStrip( window , menulist ) ;
ShowTitle( screen , TRUE ) ;
old = cells1 ;
new = cells2 ;
randseed() ;
for ( ; ; ) /* loop for each line */
{
stepauto() ;
display() ;
if ( old == cells2 )
{
old = cells1 ;
new = cells2 ;
}
else
{
old = cells2 ;
new = cells1 ;
}
if ( line == 12 )
{
if ( modes & STOPMODE )
stoploop() ;
if ( ( modes & RULEMODE ) && ( line == 12 ) )
randrule() ;
if ( ( modes & SEEDMODE ) && ( line == 12 ) )
randseed() ;
}
handlemsg() ;
}
}
void cleanup()
{
if ( window )
{
ClearMenuStrip( window ) ;
CloseWindow( window ) ;
}
if ( screen )
CloseScreen( screen ) ;
if ( GfxBase )
CloseLibrary( GfxBase ) ;
if ( IntuitionBase )
CloseLibrary( IntuitionBase ) ;
exit() ;
}
void stepauto() /* this is the actual line automation step */
{
short x , t ;
UBYTE *n , *or , *ol , *oc ;
n = new ;
switch ( neighborhood )
{
case 2 :
ol = old + precision - 1 ;
or = old + 1 ;
*( n ++ ) = rule[ *( or ++ ) + *ol ] ;
ol = old ;
for ( x = 2 ; x < precision ; x ++ )
*( n ++ ) = rule[ *( or ++ ) + *( ol ++ ) ] ;
or = old ;
*n = rule[ *or + *ol ] ;
break ;
case 3 :
t = *( old + precision - 1 ) + *( old + 1 ) + *old ;
*( n ++ ) = rule[ t ] ;
or = old + 2 ;
ol = old + precision - 1 ;
t = t - *ol + *( or ++ ) ;
*( n ++ ) = rule[ t ] ;
ol = old ;
for ( x = 3 ; x < precision ; x ++ )
{
t = t - *( ol ++ ) + *( or ++ ) ;
*( n ++ ) = rule[ t ] ;
}
or = old ;
t = t - *ol + *or ;
*n = rule[ t ] ;
break ;
case 4 :
oc = old ;
t = *( old + precision - 1 )
+ *( old + precision - 2 )
+ *( old + 2 )
+ *( old + 1 )
+ *old ;
*( n ++ ) = rule[ t - *( oc ++ ) ] ;
or = old + 3 ;
ol = old + precision - 2 ;
t = t - *( ol ++ ) + *( or ++ ) ;
*( n ++ ) = rule[ t - *( oc ++ ) ] ;
t = t - *ol + *( or ++ ) ;
*( n ++ ) = rule[ t - *( oc ++ ) ] ;
ol = old ;
for ( x = 5 ; x < precision ; x ++ )
{
t = t - *( ol ++ ) + *( or ++ ) ;
*( n ++ ) = rule[ t - *( oc ++ ) ] ;
}
or = old ;
t = t - *( ol ++ ) + *( or ++ ) ;
*( n ++ ) = rule[ t - *( oc ++ ) ] ;
t = t - *ol + *or ;
*n = rule[ t - *oc ] ;
break ;
case 5 :
t = *( old + precision - 1 )
+ *( old + precision - 2 )
+ *( old + 2 )
+ *( old + 1 )
+ *old ;
*( n ++ ) = rule[ t ] ;
or = old + 3 ;
ol = old + precision - 2 ;
t = t - *( ol ++ ) + *( or ++ ) ;
*( n ++ ) = rule[ t ] ;
t = t - *ol + *( or ++ ) ;
*( n ++ ) = rule[ t ] ;
ol = old ;
for ( x = 5 ; x < precision ; x ++ )
{
t = t - *( ol ++ ) + *( or ++ ) ;
*( n ++ ) = rule[ t ] ;
}
or = old ;
t = t - *( ol ++ ) + *( or ++ ) ;
*( n ++ ) = rule[ t ] ;
t = t - *ol + *or ;
*n = rule[ t ] ;
break ;
case 6 :
oc = old ;
t = *( old + precision - 1 )
+ *( old + precision - 2 )
+ *( old + precision - 3 )
+ *( old + 3 )
+ *( old + 2 )
+ *( old + 1 )
+ *( old ) ;
*( n ++ ) = rule[ t - *( oc ++ ) ] ;
or = old + 4 ;
ol = old + precision - 3 ;
t = t - *( ol ++ ) + *( or ++ ) ;
*( n ++ ) = rule[ t - *( oc ++ ) ] ;
t = t - *( ol ++ ) + *( or ++ ) ;
*( n ++ ) = rule[ t - *( oc ++ ) ] ;
t = t - *ol + *( or ++ ) ;
*( n ++ ) = rule[ t - *( oc ++ ) ] ;
ol = old ;
for ( x = 7 ; x < precision ; x ++ )
{
t = t - *( ol ++ ) + *( or ++ ) ;
*( n ++ ) = rule[ t - *( oc ++ ) ] ;
}
or = old ;
t = t - *( ol ++ ) + *( or ++ ) ;
*( n ++ ) = rule[ t - *( oc ++ ) ] ;
t = t - *( ol ++ ) + *( or ++ ) ;
*( n ++ ) = rule[ t - *( oc ++ ) ] ;
t = t - *ol + *or ;
*n = rule[ t - *oc ] ;
break ;
case 7 :
t = *( old + precision - 1 )
+ *( old + precision - 2 )
+ *( old + precision - 3 )
+ *( old + 3 )
+ *( old + 2 )
+ *( old + 1 )
+ *( old ) ;
*( n ++ ) = rule[ t ] ;
or = old + 4 ;
ol = old + precision - 3 ;
t = t - *( ol ++ ) + *( or ++ ) ;
*( n ++ ) = rule[ t ] ;
t = t - *( ol ++ ) + *( or ++ ) ;
*( n ++ ) = rule[ t ] ;
t = t - *ol + *( or ++ ) ;
*( n ++ ) = rule[ t ] ;
ol = old ;
for ( x = 7 ; x < precision ; x ++ )
{
t = t - *( ol ++ ) + *( or ++ ) ;
*( n ++ ) = rule[ t ] ;
}
or = old ;
t = t - *( ol ++ ) + *( or ++ ) ;
*( n ++ ) = rule[ t ] ;
t = t - *( ol ++ ) + *( or ++ ) ;
*( n ++ ) = rule[ t ] ;
t = t - *ol + *or ;
*n = rule[ t ] ;
break ;
}
}
void display() /* render cells directly to screens bit map */
{
USHORT d , i , j , k , m , *wp[ PLANES ] , *wpc[ PLANES ] ;
UBYTE cm , *c ;
if ( precision == 160 )
{
i = ( line * screen->BitMap.BytesPerRow ) ;
wp[ 0 ] = ( USHORT * ) ( screen->BitMap.Planes[ 0 ] + i ) ;
wp[ 1 ] = ( USHORT * ) ( screen->BitMap.Planes[ 1 ] + i ) ;
wp[ 2 ] = ( USHORT * ) ( screen->BitMap.Planes[ 2 ] + i ) ;
i = ( ( line + 1 ) * screen->BitMap.BytesPerRow ) ;
wpc[ 0 ] = ( USHORT * ) ( screen->BitMap.Planes[ 0 ] + i ) ;
wpc[ 1 ] = ( USHORT * ) ( screen->BitMap.Planes[ 1 ] + i ) ;
wpc[ 2 ] = ( USHORT * ) ( screen->BitMap.Planes[ 2 ] + i ) ;
c = new ;
for ( i = 0 ; i < precision ; i += 8 )
{
for ( cm = 1 , j = 0 ; j < PLANES ; j ++ , cm = cm << 1 )
{
d = 0 ;
for ( m = 0xc000 , k = 0 ; k < 8 ; m = m >> 2 , k ++ )
{
if ( *( c + k ) & cm )
d |= m ;
}
*wp[ j ] = d ;
wp[ j ] ++ ;
*wpc[ j ] = d ;
wpc[ j ] ++ ;
}
c += 8 ;
}
line += 2 ;
if ( line >= window->Height )
line = 12 ;
else
{
i = ( line * screen->BitMap.BytesPerRow ) ;
wp[ 0 ] = ( USHORT * ) ( screen->BitMap.Planes[ 0 ] + i ) ;
wp[ 1 ] = ( USHORT * ) ( screen->BitMap.Planes[ 1 ] + i ) ;
wp[ 2 ] = ( USHORT * ) ( screen->BitMap.Planes[ 2 ] + i ) ;
i = ( ( line + 1 ) * screen->BitMap.BytesPerRow ) ;
wpc[ 0 ] = ( USHORT * ) ( screen->BitMap.Planes[ 0 ] + i ) ;
wpc[ 1 ] = ( USHORT * ) ( screen->BitMap.Planes[ 1 ] + i ) ;
wpc[ 2 ] = ( USHORT * ) ( screen->BitMap.Planes[ 2 ] + i ) ;
for ( i = 0 ; i < precision ; i += 8 )
{
for ( j = 0 ; j < PLANES ; j ++ )
{
*wp[ j ] = 0 ;
wp[ j ] ++ ;
*wpc[ j ] = 0 ;
wpc[ j ] ++ ;
}
}
}
}
else
{
i = ( line * screen->BitMap.BytesPerRow ) ;
wp[ 0 ] = ( USHORT * ) ( screen->BitMap.Planes[ 0 ] + i ) ;
wp[ 1 ] = ( USHORT * ) ( screen->BitMap.Planes[ 1 ] + i ) ;
wp[ 2 ] = ( USHORT * ) ( screen->BitMap.Planes[ 2 ] + i ) ;
c = new ;
for ( i = 0 ; i < precision ; i += 16 )
{
for ( cm = 1 , j = 0 ; j < PLANES ; j ++ , cm = cm << 1 )
{
d = 0 ;
for ( m = 0x8000 , k = 0 ; k < 16 ; m = m >> 1 , k ++ )
{
if ( *( c + k ) & cm )
d |= m ;
}
*wp[ j ] = d ;
wp[ j ] ++ ;
}
c += 16 ;
}
line ++ ;
if ( line == window->Height )
line = 12 ;
else
{
i = ( line * screen->BitMap.BytesPerRow ) ;
wp[ 0 ] = ( USHORT * ) ( screen->BitMap.Planes[ 0 ] + i ) ;
wp[ 1 ] = ( USHORT * ) ( screen->BitMap.Planes[ 1 ] + i ) ;
wp[ 2 ] = ( USHORT * ) ( screen->BitMap.Planes[ 2 ] + i ) ;
for ( i = 0 ; i < precision ; i += 16 )
{
for ( j = 0 ; j < PLANES ; j ++ )
{
*wp[ j ] = 0 ;
wp[ j ] ++ ;
}
}
}
}
}
UBYTE random( a )
UBYTE a ;
{
#define RANDSHIFT 8
#define RANDTAB 23
#define RANDCOMP 8388608
static UBYTE fp = 1 ;
static long v[ RANDTAB ] , rr ;
short vi ;
if ( fp )
{
CurrentTime( &v[ 0 ] , &v[ 1 ] ) ;
srand( v[ 1 ] ) ;
for ( vi = 0 ; vi < RANDTAB ; vi ++ )
v[ vi ] = rand() >> RANDSHIFT ;
rr = rand() >> RANDSHIFT ;
fp = 0 ;
}
vi = RANDTAB * rr / RANDCOMP ;
rr = v[ vi ] ;
v[ vi ] = rand() >> RANDSHIFT ;
return ( UBYTE ) ( ( a * rr ) / RANDCOMP ) ;
}
void randrule()
{
short i , s ;
UBYTE c ;
if ( random( 2 ) )
c = 2 + random( 6 ) ; /* 2 - 7 colors */
else
c = 3 + random( 3 ) ; /* 3 - 5 colors */
s = ( ( c - 1 ) * neighborhood ) + 1 ;
do
{
for ( i = 0 ; i < s ; i ++ )
rule[ i ] = random( c ) ;
for ( ; i < RULEMAX ; i ++ )
rule[ i ] = 0 ;
if ( random( 2 ) )
rule[ 0 ] = 0 ;
for ( colors = 0 , i = 0 ; i < RULEMAX ; i ++ )
if ( rule[ i ] >= colors )
colors = rule[ i ] + 1 ;
} while ( colors <= 1 ) ;
}
void randseed()
{
short x ;
line = 12 ;
for ( x = 0 ; x < precision ; x ++ )
*( new + x ) = random( colors ) ;
display() ;
if ( old == cells2 )
{
old = cells1 ;
new = cells2 ;
}
else
{
old = cells2 ;
new = cells1 ;
}
}
void handlemsg()
{
while ( mes = GetMsg( window->UserPort ) )
{
class = mes->Class ;
code = mes->Code ;
ReplyMsg( mes ) ;
switch ( class )
{
case MENUVERIFY :
Wait( 1 << window->UserPort->mp_SigBit ) ;
while ( class != MENUPICK )
{
if ( mes = GetMsg( window->UserPort ) )
{
class = mes->Class ;
code = mes->Code ;
ReplyMsg( mes ) ;
}
}
case MENUPICK :
handlemenu() ;
break ;
}
}
}
void handlemenu()
{
short i , j ;
switch ( MENUNUM( code ) )
{
case 0 : /* control */
switch ( ITEMNUM( code ) )
{
case 0 : /* stop */
stoploop() ;
break ;
case 1 : /* continue */
stopflag = 0 ;
break ;
case 2 : /* precision */
switch ( SUBNUM( code ) )
{
case 0 :
switch ( precision )
{
case 160 :
break ;
case 320 :
line = 12 ;
break ;
case 640 :
line = 12 ;
ns.Width = 320 ;
ns.Height = 200 ;
ns.ViewModes = 0 ;
nw.Width = 320 ;
nw.Height = 200 ;
ClearMenuStrip( window ) ;
CloseWindow( window ) ;
CloseScreen( screen ) ;
window = NULL ;
screen = OpenScreen( &ns ) ;
if ( screen )
window = OpenWindow( &nw ) ;
if ( window )
{
SetMenuStrip( window , menulist ) ;
for ( i = 0 ; i < CMAX ; i ++ )
SetRGB4( &screen->ViewPort , i , ctab[ i ][ 0 ] ,
ctab[ i ][ 1 ] ,
ctab[ i ][ 2 ] ) ;
}
else
{
cleanup() ;
}
break ;
}
precision = 160 ;
precisionsub[ 1 ].item.Flags = precisionsub[ 1 ].item.Flags
& ( ~ CHECKED ) ;
precisionsub[ 2 ].item.Flags = precisionsub[ 2 ].item.Flags
& ( ~ CHECKED ) ;
break ;
case 1 :
switch ( precision )
{
case 160 :
line = 12 ;
for ( i = 0 ; i < 160 ; i ++ )
*( old + 160 + i ) = *( old + i ) ;
break ;
case 320 :
break ;
case 640 :
line = 12 ;
ns.Width = 320 ;
ns.Height = 200 ;
ns.ViewModes = 0 ;
nw.Width = 320 ;
nw.Height = 200 ;
ClearMenuStrip( window ) ;
CloseWindow( window ) ;
CloseScreen( screen ) ;
window = NULL ;
screen = OpenScreen( &ns ) ;
if ( screen )
window = OpenWindow( &nw ) ;
if ( window )
SetMenuStrip( window , menulist ) ;
else
cleanup() ;
for ( i = 0 ; i < CMAX ; i ++ )
SetRGB4( &screen->ViewPort , i , ctab[ i ][ 0 ] ,
ctab[ i ][ 1 ] ,
ctab[ i ][ 2 ] ) ;
break ;
}
precision = 320 ;
precisionsub[ 0 ].item.Flags = precisionsub[ 0 ].item.Flags
& ( ~ CHECKED ) ;
precisionsub[ 2 ].item.Flags = precisionsub[ 2 ].item.Flags
& ( ~ CHECKED ) ;
break ;
case 2 :
switch ( precision )
{
case 160 :
for ( i = 0 ; i < 160 ; i ++ )
*( old + 160 + i ) = *( old + i ) ;
case 320 :
for ( i = 0 ; i < 320 ; i ++ )
*( old + 320 + i ) = *( old + i ) ;
line = 12 ;
ns.Width = 640 ;
ns.Height = 400 ;
ns.ViewModes = HIRES | LACE ;
nw.Width = 640 ;
nw.Height = 400 ;
ClearMenuStrip( window ) ;
CloseWindow( window ) ;
CloseScreen( screen ) ;
window = NULL ;
screen = OpenScreen( &ns ) ;
if ( screen )
window = OpenWindow( &nw ) ;
if ( window )
{
for ( i = 0 ; i < CMAX ; i ++ )
SetRGB4( &screen->ViewPort , i , ctab[ i ][ 0 ] ,
ctab[ i ][ 1 ] ,
ctab[ i ][ 2 ] ) ;
SetMenuStrip( window , menulist ) ;
precision = 640 ;
precisionsub[ 0 ].item.Flags =
precisionsub[ 0 ].item.Flags & ( ~ CHECKED ) ;
precisionsub[ 1 ].item.Flags =
precisionsub[ 1 ].item.Flags & ( ~ CHECKED ) ;
}
else
{
ns.Width = 320 ;
ns.Height = 200 ;
ns.ViewModes = 0 ;
nw.Width = 320 ;
nw.Height = 200 ;
if ( screen )
CloseScreen( screen ) ;
screen = OpenScreen( &ns ) ;
if ( screen )
window = OpenWindow( &nw ) ;
if ( window )
SetMenuStrip( window , menulist ) ;
else
cleanup() ;
for ( i = 0 ; i < CMAX ; i ++ )
SetRGB4( &screen->ViewPort , i , ctab[ i ][ 0 ] ,
ctab[ i ][ 1 ] ,
ctab[ i ][ 2 ] ) ;
SetAPen( window->RPort , 7 ) ;
Move( window->RPort , 10 , 140 ) ;
Text( window->RPort ,
"Unable to open high res screen" , 30 ) ;
precision = 320 ;
precisionsub[ 0 ].item.Flags =
precisionsub[ 0 ].item.Flags & ( ~ CHECKED ) ;
precisionsub[ 1 ].item.Flags =
precisionsub[ 1 ].item.Flags | CHECKED ;
precisionsub[ 2 ].item.Flags =
precisionsub[ 2 ].item.Flags & ( ~ CHECKED ) ;
}
break ;
case 640 :
break ;
}
break ;
}
break ;
case 3 : /* neighborhood */
neighborhood = 2 + SUBNUM( code ) ;
break ;
case 4 : /* modes */
switch ( SUBNUM( code ) )
{
case 0 :
modes = modes ^ STOPMODE ;
break ;
case 1 :
modes = modes ^ SEEDMODE ;
break ;
case 2 :
modes = modes ^ RULEMODE ;
break ;
}
break ;
case 5 : /* quit */
cleanup() ;
break ;
}
break ;
case 1 : /* rule */
switch ( ITEMNUM( code ) )
{
case 0 :
randrule() ;
break ;
case 1 :
for ( i = RULEMAX - 1 ; ( i >= 0 ) && ( ! rule[ i ] ) ; i -- )
;
for ( j = 0 ; i >= 0 ; i -- , j ++ )
buff[ j ] = rule[ i ] + 48 ;
buff[ j ] = 0 ;
if ( stringreq( " Enter New Rule " , RULEMAX + 1 ) )
{
for ( i = 0 ; ( i < RULEMAX + 1 ) && ( buff[ i ] ) ; i ++ )
;
for ( j = 0 , i -- ; i >= 0 ; i -- , j ++ )
rule[ j ] = ( buff[ i ] - 48 ) & 7 ;
for ( ; j < RULEMAX ; j ++ )
rule[ j ] = 0 ;
for ( colors = 0 , i = 0 ; i < RULEMAX ; i ++ )
if ( rule[ i ] >= colors )
colors = rule[ i ] + 1 ;
}
break ;
}
break ;
case 2 : /* seed */
switch ( ITEMNUM( code ) )
{
case 0 :
randseed() ;
break ;
case 1 :
for ( i = 0 ; ( i < SEEDMAX + 1 ) && ( oldseed[ i ] != 255 ) ; i ++ )
buff[ i ] = oldseed[ i ] + 48 ;
buff[ i ] = 0 ;
if ( stringreq( " Enter New Seed " , SEEDMAX + 1 ) )
{
for ( i = 0 ; ( i < SEEDMAX + 1 ) && buff[ i ] ; i ++ )
oldseed[ i ] = ( buff[ i ] - 48 ) & 7 ;
oldseed[ i ] = 255 ;
}
else
break ;
case 2 :
line = 12 ;
for ( i = 0 ; i < precision ; i ++ )
*( new + i ) = 0 ;
j = ( precision >> 1 ) - 10 ;
for ( i = 0 ; ( i < SEEDMAX ) && ( oldseed[ i ] != 255 ) ; i ++ )
*( new + i + j ) = oldseed[ i ] ;
display() ;
if ( old == cells2 )
{
old = cells1 ;
new = cells2 ;
}
else
{
old = cells2 ;
new = cells1 ;
}
break ;
}
break ;
}
}
void stoploop()
{
if ( ! stopflag )
{
stopflag = 1 ;
while ( stopflag )
{
Wait( 1 << window->UserPort->mp_SigBit ) ;
handlemsg() ;
}
}
}
short stringreq( t , l )
UBYTE *t ;
short l ;
{
struct Window *rw ;
struct Gadget *g ;
long sig ;
rnw.Title = t ;
rnw.Screen = screen ;
reqinfo.BufferPos = 0 ;
reqinfo.DispPos = 0 ;
reqinfo.MaxChars = l ;
rw = OpenWindow( &rnw ) ; /* a window but it looks like a requester */
if ( rw )
{
sig = ( 1 << window->UserPort->mp_SigBit )
| ( 1 << rw->UserPort->mp_SigBit ) ;
while ( class != GADGETUP )
{
Wait( sig ) ;
while ( mes = GetMsg( window->UserPort ) )
{
if ( ( mes->Class == MENUVERIFY ) && ( mes->Code == MENUHOT ) )
mes->Code = MENUCANCEL ;
ReplyMsg( mes ) ;
}
while ( mes = GetMsg( rw->UserPort ) )
{
class = mes->Class ;
g = ( struct Gadget * ) mes->IAddress ;
ReplyMsg( mes ) ;
}
}
CloseWindow( rw ) ;
if ( g->GadgetID == 3 )
return 0 ;
else
return 1 ;
}
else
{
DisplayBeep( screen ) ;
return 0 ;
}
}